/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ibmmodel3;

import AlignmentHelper.IO;
import ParTreeVisualizer.ParallelTreeVisualizer;
import ParTreeVisualizer.SentenceAlignement;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 *
 * @author mwh
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
//        Alignment a = new Alignment(1, 2);


//        FertilityTableMem ftMem = new FertilityTableMem("/home/mwh/DGS/gizafiles/full/en-da.n3.final");
//        FertilityTable fertJDBM = new FertilityTableJDBM(ftMem, "en-da.n3");
//        
//        DistortionTableMem distMem = new DistortionTableMem("/home/mwh/DGS/gizafiles/full/da-en.a3.final");
//        DistortionTable distJDBM = new DistortionTableJDBM(distMem, "da-en.a3");
//
//        TranslationTableMem trans = new TranslationTableMem("/home/mwh/DGS/gizafiles/full/en-da.t3.final");
//        TranslationTable t = new TranslationTableJDBM(trans, "en-da.t3.db");
//        VocabularyTableMem vocabdaMem = new VocabularyTableMem("/home/mwh/DGS/gizafiles/full/da.vcb");
//        VocabularyTable vda = new VocabularyTableJDBM(vocabdaMem, "da.vcb");
//
//        VocabularyTableMem vocabenMem = new VocabularyTableMem("/home/mwh/DGS/gizafiles/full/en.vcb");
//        VocabularyTable ven = new VocabularyTableJDBM(vocabenMem, "en.vcb");
//
        
//        FertilityTableMem ftMem = new FertilityTableMem("/home/mwh/DGS/gizafiles/full/da-en.n3.final");
//        FertilityTable fertJDBM = new FertilityTableJDBM(ftMem, "da-en.n3");
//
//        DistortionTableMem distMem = new DistortionTableMem("/home/mwh/DGS/gizafiles/full/en-da.a3.final");
//        DistortionTable distJDBM = new DistortionTableJDBM(distMem, "en-da.a3");
//
//        TranslationTableMem trans = new TranslationTableMem("/home/mwh/DGS/gizafiles/full/da-en.t3.final");
//        TranslationTable t = new TranslationTableJDBM(trans, "da-en.db");
//
//
//
////        String a = "Indenringsministeriet";
//        String b = "Ministry";
//        System.err.println(AlignmentHelper.LCS.LCSAlgorithm(a, b));        
//        System.err.println(AlignmentHelper.LCS.lcsSimple(a, b));


    //  makeCorp();
     //   readACL();
    //Aligner.test(20);
    //hej();

      readACL2();
//        TranslationTableMem trans = new TranslationTableMem("/home/mwh/DGS/gizafiles/full/en-da.t3.final");
//
//        TranslationTable t = new TranslationTableJDBM(trans, "en-da.t3.db");


    //TranslationTable t = new TranslationTableJDBM("en-da.t3.db");



//        TranslationTable t = new TranslationTableJDO(trans, "en-da.t3.db");

//          TranslationTable t = new TranslationTableJDO("tt");
//        
    //System.err.println(t.get(13, 13));
//        
//
//        PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory("jpox.properties");
//        PersistenceManager pm = pmf.getPersistenceManager();
//
//        Transaction tx = pm.currentTransaction();
//
//        try {
//            tx.begin();
//
//
//
////            System.err.println(pm.makePersistent(a));
////            System.err.println(pm.makePersistent(trans));
//
//            tx.commit();
//            tx = pm.currentTransaction();
//            tx.begin();
//            Query q = pm.newQuery(Alignment.class);
//            System.err.println(q.execute());
//            q = pm.newQuery(TranslationTableMem.class);
//            List<TranslationTable> l = (List<TranslationTable>) q.execute();
//            System.err.println(l);
//            TranslationTableMem t = (TranslationTableMem) l.get(0);
//            System.err.println(t);
//            System.err.println(t.table);
//
//
//        } finally {
//            if (tx.isActive()) {
//                tx.rollback();
//            }
//            pm.close();
//        }





    }


    public static void readACL2() throws Exception {

        List<List<String>> da = AlignmentHelper.IO.readACLText("/home/mwh/DGS/1051.acl.slang");
        List<List<String>> en = AlignmentHelper.IO.readACLText("/home/mwh/DGS/1051.acl.tlang");

        List<SentenceAlignement> sal = AlignmentHelper.IO.readACLAlignment("/home/mwh/DGS/1051.my.symal.acl", da, en);

        ParallelTreeVisualizer pt = new ParallelTreeVisualizer();
        pt.visualize(sal);
    }
  public static void readACL3() throws Exception {

        List<List<String>> da = AlignmentHelper.IO.readACLText("/home/mwh/DGS/1051.acl.slang");
        List<List<String>> en = AlignmentHelper.IO.readACLText("/home/mwh/DGS/1051.acl.tlang");


        DistortionTable distJDBM = new DistortionTableJDBM("en-da.a3");
        DistortionTable dist = new DistortionTableCache(distJDBM, 1000);

        FertilityTable fertJDBM = new FertilityTableJDBM("da-en.n3");
        FertilityTable fert = new FertilityTableCache(fertJDBM, 1000);

        TranslationTable transJDBM = new TranslationTableJDBM("da-en.t3.db");
        TranslationTable trans = new TranslationTableCache(transJDBM, 1000);

        VocabularyTable vocabdaJDBM = new VocabularyTableJDBM("da.vcb");
        VocabularyTable vocabda = new VocabularyTableCache(vocabdaJDBM, 1000);

        VocabularyTable vocabenJDBM = new VocabularyTableJDBM("en.vcb");
        VocabularyTable vocaben = new VocabularyTableCache(vocabenJDBM, 1000);

        ZeroFertility p0 = new ZeroFertility("/home/mwh/DGS/gizafiles/full/da-en.p0_3.final");

        List<GIZAAlignment> gal = new ArrayList<GIZAAlignment>();
        for (int i = 1; i < da.size(); i++) {
            List<String> s1 = en.get(i);
            List<String> s2 = da.get(i);
            GIZAAlignment ga = new GIZAAlignment(s1, s2, trans, dist, fert, vocaben, vocabda, p0);
            gal.add(ga);
        }

        long a = System.currentTimeMillis();
        for (GIZAAlignment ga : gal) {
            Aligner.align(ga);
        }
        long b = System.currentTimeMillis();
        long t = b - a;
        System.err.println("TIME: " + t);

        List<SentenceAlignement> sal = new ArrayList<SentenceAlignement>();
        for (GIZAAlignment ga : gal) {
            sal.add(ga.getSA());

        }

//        GIZAAlignment ga = gal.get(0);
//        System.err.println(ga.score());
//         System.err.println(ga.res + " = " + ga.Pchooselog + " + " + ga.Pp0log + " + " + ga.Pp1log + " + " + ga.Psprodlog + " + " + ga.Ptprodlog);
//
//            System.err.println(Math.pow(10, ga.res) + " = " + Math.pow(10, ga.Pchooselog) + " * " + Math.pow(10, ga.Pp0log) + " * " + Math.pow(10, ga.Pp1log) +
//                    " * " + Math.pow(10, ga.Psprodlog) + " * " + Math.pow(10, ga.Ptprodlog));
//        
//        alignRes ar = ga.tryAlign(4, 5,true);
//        ga.apply(ar);
//        System.err.println(ga.score());
//        sal.add(ga.getSA());

        ParallelTreeVisualizer pt = new ParallelTreeVisualizer();
        pt.visualize(sal);

        AlignmentHelper.IO.writeGIZA(gal, "/home/mwh/DGS/1051-en-da.bal");
        //AlignmentHelper.IO.writeACLAlignment(sal, "/home/mwh/DGS/tt1051");

    }



    public static void readACL() throws Exception {

        List<List<String>> da = AlignmentHelper.IO.readACLText("/home/mwh/DGS/1051.acl.slang");
        List<List<String>> en = AlignmentHelper.IO.readACLText("/home/mwh/DGS/1051.acl.tlang");


        DistortionTable distJDBM = new DistortionTableJDBM("da-en.a3");
        DistortionTable dist = new DistortionTableCache(distJDBM, 1000);

        FertilityTable fertJDBM = new FertilityTableJDBM("en-da.n3");
        FertilityTable fert = new FertilityTableCache(fertJDBM, 1000);

        TranslationTable transJDBM = new TranslationTableJDBM("en-da.t3.db");
        TranslationTable trans = new TranslationTableCache(transJDBM, 1000);

        VocabularyTable vocabdaJDBM = new VocabularyTableJDBM("da.vcb");
        VocabularyTable vocabda = new VocabularyTableCache(vocabdaJDBM, 1000);

        VocabularyTable vocabenJDBM = new VocabularyTableJDBM("en.vcb");
        VocabularyTable vocaben = new VocabularyTableCache(vocabenJDBM, 1000);

        ZeroFertility p0 = new ZeroFertility("/home/mwh/DGS/gizafiles/full/da-en.p0_3.final");

        List<GIZAAlignment> gal = new ArrayList<GIZAAlignment>();
        for (int i = 1; i < da.size(); i++) {
            List<String> s1 = da.get(i);
            List<String> s2 = en.get(i);
            GIZAAlignment ga = new GIZAAlignment(s1, s2, trans, dist, fert, vocabda, vocaben, p0);
            gal.add(ga);
        }

        long a = System.currentTimeMillis();
        for (GIZAAlignment ga : gal) {
            Aligner.align(ga);
        }
        long b = System.currentTimeMillis();
        long t = b - a;
        System.err.println("TIME: " + t);

        List<SentenceAlignement> sal = new ArrayList<SentenceAlignement>();
        for (GIZAAlignment ga : gal) {
            sal.add(ga.getSA());

        }

//        GIZAAlignment ga = gal.get(0);
//        System.err.println(ga.score());
//         System.err.println(ga.res + " = " + ga.Pchooselog + " + " + ga.Pp0log + " + " + ga.Pp1log + " + " + ga.Psprodlog + " + " + ga.Ptprodlog);
//
//            System.err.println(Math.pow(10, ga.res) + " = " + Math.pow(10, ga.Pchooselog) + " * " + Math.pow(10, ga.Pp0log) + " * " + Math.pow(10, ga.Pp1log) +
//                    " * " + Math.pow(10, ga.Psprodlog) + " * " + Math.pow(10, ga.Ptprodlog));
//        
//        alignRes ar = ga.tryAlign(4, 5,true);
//        ga.apply(ar);
//        System.err.println(ga.score());
//        sal.add(ga.getSA());

        ParallelTreeVisualizer pt = new ParallelTreeVisualizer();
        pt.visualize(sal);

        AlignmentHelper.IO.writeGIZA(gal, "/home/mwh/DGS/1051-da-en.bal");
        //AlignmentHelper.IO.writeACLAlignment(sal, "/home/mwh/DGS/tt1051");

    }


    public static void makeCorp() throws Exception {

        List<SentenceAlignement> all = new ArrayList<SentenceAlignement>();

        BufferedReader input = new BufferedReader(new FileReader("/home/mwh/DGS/cdt/atagfiles.lst"));

        String line;


        while ((line = input.readLine()) != null) {

            System.err.println(line);
            List<SentenceAlignement> sal = IO.readATAG("/home/mwh/DGS/cdt/da-en/" + line);
            all.addAll(sal);
        }

        for (SentenceAlignement sa : all) {
        //System.err.println(sa);
        }

        AlignmentHelper.IO.writeACLAlignment(all, "/home/mwh/DGS/1051");
        ParallelTreeVisualizer pt = new ParallelTreeVisualizer();
        pt.visualize(all);

    }


    public static void hej() throws Exception {

//        List<SentenceAlignement> sal =  IO.readATAG("/home/mwh/DGS/cdtfiles/0021-dk-en.atag.utf");
//         ParallelTreeVisualizer pt = new ParallelTreeVisualizer();
//    //     pt.visualize(sal);
//                
//        IO.writeUPlugXML(sal, "/home/mwh/DGS/uplug1");

        long at = System.currentTimeMillis();
//        DistortionTable distGrep = new DistortionTableGrep("/home/mwh/DGS/gizafiles/full/da-en.a3.final");
//        DistortionTable dist = new DistortionTableCache(distGrep, 1000);

        DistortionTable distJDBM = new DistortionTableJDBM("da-en.a3");
        DistortionTable dist = new DistortionTableCache(distJDBM, 1000);


        //System.err.println(dist.get(new DistortionKey(1, 1, 1, 100)));

//        FertilityTable fertGrep = new FertilityTableGrep("/home/mwh/DGS/gizafiles/full/da-en.n3.final");
//        FertilityTable fert = new FertilityTableCache(fertGrep, 1000);

        FertilityTable fertJDBM = new FertilityTableJDBM("en-da.n3");
        FertilityTable fert = new FertilityTableCache(fertJDBM, 1000);

//        System.err.println(fert.get(6));
        //System.err.println(fert.get(6, 10));



        //   TranslationTableGrep trans = new TranslationTableGrep("/home/mwh/DGS/gizafiles/full/en-da.t3.final");
        //   TranslationTable trans = new TranslationTableCache(transGrep);
//          TranslationTable transMem = new TranslationTableMem("/home/mwh/DGS/gizafiles/full/en-da.t3.final");
//             TranslationTable trans = new TranslationTableCache(transMem);
        TranslationTable transJDBM = new TranslationTableJDBM("en-da.t3.db");
        TranslationTable trans = new TranslationTableCache(transJDBM, 1000);

        //      System.err.println(trans.get(31));
        //System.err.println(trans.get(31, 71));

        //VocabularyTable vocabda = new VocabularyTableMem("/home/mwh/DGS/gizafiles/full/da.vcb");
        //VocabularyTable vocabdaGrep = new VocabularyTableGrep("/home/mwh/DGS/gizafiles/full/da.vcb");

        VocabularyTable vocabdaJDBM = new VocabularyTableJDBM("da.vcb");
        VocabularyTable vocabda = new VocabularyTableCache(vocabdaJDBM, 1000);
        //System.err.println("---------------------------------------------");
        //VocabularyTable vocabenGrep = new VocabularyTableGrep("/home/mwh/DGS/gizafiles/full/en.vcb");
        VocabularyTable vocabenJDBM = new VocabularyTableJDBM("en.vcb");
        VocabularyTable vocaben = new VocabularyTableCache(vocabenJDBM, 1000);
        //  System.err.println(vocabda.get("som"));
        //System.err.println(vocabda.get(24));

        ZeroFertility p0 = new ZeroFertility("/home/mwh/DGS/gizafiles/full/da-en.p0_3.final");


        //System.err.println(p0.get());

        List<List<String>> da = new ArrayList<List<String>>();
        List<List<String>> en = new ArrayList<List<String>>();
        BufferedReader input = new BufferedReader(new FileReader("/home/mwh/DGS/1047da.utf.txt"));
        String line;
        while ((line = input.readLine()) != null) {

            String[] sa1 = line.split(" ");
            List<String> s1 = (List<String>) Arrays.asList(sa1);
            da.add(s1);
        }
//
        input = new BufferedReader(new FileReader("/home/mwh/DGS/1047en.utf.txt"));

        while ((line = input.readLine()) != null) {

            String[] sa2 = line.split(" ");
            List<String> s2 = (List<String>) Arrays.asList(sa2);
            en.add(s2);
        }


//  
//        System.err.println(da);
//        System.err.println(en);


        List<GIZAAlignment> gal = new ArrayList<GIZAAlignment>();
        for (int i = 0; i < da.size(); i++) {
            List<String> s1 = da.get(i);
            List<String> s2 = en.get(i);
            GIZAAlignment ga = new GIZAAlignment(s1, s2, trans, dist, fert, vocabda, vocaben, p0);
            gal.add(ga);
        }
//
//        s1.add("Hans");
//        s1.add("kører");
//        s1.add("bil");
//        s1.add("i");
//        s1.add("dag");
//
//        s2.add("Hans");
//        s2.add("drives");
//        s2.add("a");
//        s2.add("car");
//        s2.add("today");
//

        for (GIZAAlignment ga : gal) {
            Aligner.align(ga);
        }

        List<SentenceAlignement> sal = new ArrayList<SentenceAlignement>();
        for (GIZAAlignment ga : gal) {
            sal.add(ga.getSA());

        }


        long bt = System.currentTimeMillis();
        long tt = bt - at;



        GIZAAlignment gg = gal.get(0);
        System.err.println("***************");
        //        for (Integer k : ga.a.keySet()) {
//            System.err.println(k + " : " + ga.a.get(k));
//        }

        System.err.println(gg.tryAlign(3, 5, false));


        for (Integer k : gg.a.keySet()) {
            System.err.println(k + " : " + gg.a.get(k));
        }

//
//        GIZAAlignment ga = new GIZAAlignment(s1, s2, trans, dist, fert, vocabda, vocaben, p0);
//
//        Aligner.align(ga);
//
//        for (Integer k : ga.a.keySet()) {
//            System.err.println(k + " : " + ga.a.get(k));
//        }
//
//
        //List<SentenceAlignement> sal = new ArrayList<SentenceAlignement>();
//
//        SentenceAlignement sa = ga.getSA();
//        for (WordAlignement wa : sa.a) {
//            System.err.println(wa);
//
//        }
//        System.err.println(sa.s1);
//        System.err.println(sa.s2);
//
//        sal.add(sa);
        ParallelTreeVisualizer pt = new ParallelTreeVisualizer();
        pt.visualize(sal);
//

        System.err.println("Total time: " + tt);

//        ga.addAlignment(1, 1);
//        for (Integer k : ga.a.keySet()) {
//            System.err.println(k + " : " + ga.a.get(k));
//        }
////        System.err.println(ga.update());
//        ga.tryAlign(2, 2);

    // ga.addAlignment(2, 2);
//        for (Integer k : ga.a.keySet()) {
//            System.err.println(k + " : " + ga.a.get(k));
//        }
//        System.err.println(ga.update());

//        SentenceAlignement sa = ga.getSA();
//        List<SentenceAlignement> sal = new ArrayList<SentenceAlignement>();
//        sal.add(sa);
//        ParallelTreeVisualizer pt = new ParallelTreeVisualizer();
//        pt.visualize(sal);
////
////
//        ga.addAlignment(2, 2);
//        System.err.println(ga.update());
//        sal.add(ga.getSA());
//        
//        ga.addAlignment(1, 1);
//        System.err.println(ga.update());
//        sal.add(ga.getSA());
////
////
////
////        ga.addAlignment(3, 4);
////        ga.addAlignment(2, 2);
////        ga.addAlignment(3, 3);
////        ga.update();
////        sal.add(ga.getSA());
////
////
////        long bt = System.currentTimeMillis();
////        long time = bt - at;
////        System.err.println("----------------\n----  " + time + "ms    -----\n--------------");
////System.err.println("VocabLoadTime: " + vt);
////        List<GIZAAlignment> lga = new ArrayList<GIZAAlignment>();
////        lga.add(ga);
////        IO.writeGIZA(lga, "/home/mwh/DGS/test1.gza");
//
//          pt.visualize(sal);                    
//          
    }


    public static long pos(int n, int m) {
        long res = 0;
        int maxA = 5;
        int rem = m;
        for (int i = 1; i <= maxA; i++) {
            res = res + choose(rem, i);
            rem--;

        }
        res = res * n;
        return res;

    }

    // Compute n choose k, which is the number of ways you can choose k objects
    // out of a set of n.  It is equal to n! / (k! * (n-k)!) .
    public static long choose(int n, int k) {
        return fact(n) / (fact(k) * fact(n - k));
    }

    // Compute n!.
    public static long fact(int n) {
        long answer = 1;    // Accumulate the product

        for (long i = 1; i <= n; i++) {
            answer *= i;
        }

        return answer;
    }
}
